﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Domain;
using Spider.Service;

namespace Spider.Spiders
{
    /// <summary>
    /// 蜘蛛指挥官
    /// </summary>
    internal class SpiderCaptain
    {
        private bool _isWork = false;
        internal static string StopWorkReason { get; set; }
        internal static int WorkSpeed { get; set; }
        internal static DateTime StarTime { get; set; }
        internal static DateTime EndTime { get; set; }
        internal static bool IsSTA { get; set; }//是否单线程模式工作
        private static SpiderCaptain _spiderCaptain;
        private static readonly object _syncBoot = new object();
        private SpiderCaptain()
        {

        }
        public static SpiderCaptain GetInstance()
        {
            if (_spiderCaptain == null)
            {
                lock (_syncBoot)
                {
                    if (_spiderCaptain == null)
                    {
                        _spiderCaptain = new SpiderCaptain();
                    }
                }
            }
            return _spiderCaptain;
        }
        /// <summary>
        /// 蜘蛛队长是否在工作
        /// </summary>
        public bool IsWorking { get { return _isWork; } }
        /// <summary>
        ///  开始工作
        /// </summary>
        public void StartToWork()
        {
            _isWork = true;
            StarTime = DateTime.Now;
            DoWork();
        }
        /// <summary>
        ///  开始工作,单线程模型
        /// </summary>
        public void StartToWorkBySTA(WebBrowser browser)
        {
            Spider.WebBrowser = browser;
            _isWork = true;
            IsSTA = true;
            StarTime = DateTime.Now;
            StopWorkReason = string.Empty;
            DoWork();
        }
        /// <summary>
        /// 停止工作
        /// </summary>
        public void StopToWork(string reason = "")
        {
            _isWork = false;
            EndTime = DateTime.Now;
            StopWorkReason = reason;
        }
        /// <summary>
        /// 指挥蜘蛛工作
        /// </summary>
        private void DoWork()
        {
            while (_isWork)
            {
                ToDoData toDoData = null;
                try
                {
                    toDoData = GetUrlFromToDoQueue();
                    if (toDoData != null)
                    {

                        Thread.Sleep(WorkSpeed);//工作速度
                        //单线程模式
                        if (IsSTA)
                        {
                            DispatchTask(toDoData);
                        }
                        else
                        {
                            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
                            {
                                DispatchTask(toDoData);
                            }));
                        }


                    }
                    //队列为空则休眠10秒再次工作
                    else
                    {
                        if (IsSTA)
                            Application.DoEvents();
                        else
                            Thread.Sleep(10000);
                    }
                }
                catch (Exception ex)
                {
                    CustomsLog.WriteExceptionErrorLog("蜘蛛队长分派任务出错", ex);
                }
            }
        }

        /// <summary>
        /// 从待趴取队列获取网络地址
        /// </summary>
        /// <returns></returns>
        private ToDoData GetUrlFromToDoQueue()
        {
            return ToDo.GetUrl();
        }

        /// <summary>
        /// 给蜘蛛分派任务
        /// </summary>
        /// <param name="pageData"></param>
        private void DispatchTask(ToDoData pageData)
        {
            switch (pageData.DataSource)
            {
                case PageDataSource.QQVisitor:
                    SpiderMother.GetInstance().CreateQqSprider().StartToWork(pageData);
                    break;
                case PageDataSource.QQSeed:
                    SpiderMother.GetInstance().CreateQqSprider().StartToWork(pageData);
                    break;
                case PageDataSource.QQNumberForZone:
                    SpiderMother.GetInstance().CreateQqSprider().StartToWork(pageData);
                    break;
                case PageDataSource.QQNumberForWb:
                    SpiderMother.GetInstance().CreateQqWbSprider().StartToWork(pageData);
                    break;
                case PageDataSource.Ygdy8netIndexPage:
                    SpiderMother.GetInstance().CreateYgdy8netSprider().StartToWork(pageData);
                    break;
                default: break;
            }
        }

    }
}
